扩展 CadQuery
目录
如果您发现 CadQuery 不能满足您的需求,您可以轻松扩展它。CadQuery 提供了几种扩展方法:
您可以加载其他人开发的插件。这是迄今为止访问其他代码的最简单方法
您可以定义自己的插件。
您可以直接使用 OCP 脚本
使用 OpenCascade 方法
扩展 CadQuery 的最简单方法是在构建方法中使用 OpenCascade/OCP 脚本。几乎任何有效的 OCP 脚本都可以正常执行。例如,这个简单的 CadQuery 脚本:
return cq.Workplane("XY").box(1.0, 2.0, 3.0).val()
实际上相当于:
return cq.Shape.cast(
BRepPrimAPI_MakeBox(
gp_Ax2(Vector(-0.1, -1.0, -1.5), Vector(0, 0, 1)), 1.0, 2.0, 3.0
).Shape()
)
只要返回有效的 OCP Shape,您就可以使用任何您喜欢的 OCP 方法。您甚至可以将两者混合搭配。例如,考虑以下脚本,它创建一个 OCP 盒子,然后使用 CadQuery 选择它的面:
box = cq.Shape.cast(
BRepPrimAPI_MakeBox(
gp_Ax2(Vector(-0.1, -1.0, -1.5), Vector(0, 0, 1)), 1.0, 2.0, 3.0
).Shape()
)
cq = Workplane(box).faces(">Z").size() # returns 6
扩展 CadQuery:插件
尽管您可以使用 OpenCascade 完成很多工作,但代码很快就会变得非常糟糕。CadQuery 使您免受 OpenCascade API 的许多复杂性的影响。
通过将 OCP 脚本封装到 CadQuery 插件中,您可以两全其美。
CadQuery 插件只是附加到 CadQuerycadquery.CQ()
或cadquery.Workplane()
类的一个函数。连接后,您的插件可以像内置函数一样在链中使用。
构建插件时需要理解一些重要的关键概念
堆栈
每个 CadQuery 对象都有一个本地堆栈,其中包含一个项目列表。堆栈上的项目将是以下类型之一:
一个 CadQuery SolidReference 对象,它保存对 OCP 实体的引用
OCP 对象,顶点 Vertex、边 Edge、线 Wire、面 Face、壳 Shell、实体 Solid 或复合 Compound
该堆栈可通过使用 self.objects
来使用,并且始终包含至少一个对象。
堆栈上的对象和点始终位于全局坐标中。同样,您创建的任何对象也必须根据全局坐标创建!
保护链条
CadQuery 的流畅 API 依赖于将调用一个接一个地链接在一起的能力。为此,您必须返回有效的 CadQuery 对象作为返回值。如果您选择不返回 CadQuery 对象,那么您的插件将结束该链。有时这是需要的,例如cadquery.Workplane.size()
您可以通过两种方式安全地继续该链:
return self 如果您只是想修改堆栈内容,则可以简单地返回对 self 的引用。这种做法是破坏性的,因为栈的内容被修改了,但它也是最简单的。
cadquery.Workplane.newObject()
大多数时候,您想要返回一个新对象。使用 newObject 将返回一个具有您指定的堆栈的新 CQ 或 Workplane 对象,并将该对象链接到前一个对象。这会保留原始对象及其堆栈。
辅助方法
当您实现 CadQuery 插件时,您正在扩展 CadQuery 的基础对象。因此,您可以从扩展内部调用任何 CadQuery 或 Workplane 方法。您还可以调用一些内部方法,以帮助创建插件:
cadquery.Workplane._makeWireAtPoints()
将为堆栈上的所有点调用您提供的工厂函数,并返回正确构造的 cadquery 对象。该函数负责为您处理注册的线以及类似的事情cadquery.Workplane.newObject()
返回一个新的 Workplane 对象,其中包含提供的堆栈,并将其父级设置为当前对象。这是延续链条的首选方式cadquery.Workplane.findSolid()
返回链中找到的第一个实体,从链中的当前对象向上工作。当您的插件将修改现有实体或需要创建对象然后将它们组合到正在进行的“主要”部分时通常使用cadquery.Workplane._addPendingWire()
如果添加电线,则必须调用。这允许基类跟踪创建的所有连线,以便在发生挤压时可以管理它们。cadquery.Workplane.wire()
收集所有已绘制的边(例如,按线、vline 等),并尝试将它们组合成一条返回的线。当您的插件创建 2D 边缘并且您知道是时候将它们收集到单线中时,应该使用此方法。cadquery.Workplane.plane()
提供对工作平面的引用,允许您在工作平面坐标和全局坐标之间进行转换: *cadquery.occ_impl.geom.Plane.toWorldCoords()
将局部坐标转换为全局坐标 *cadquery.occ_impl.geom.Plane.toLocalCoords()
将全局坐标转换为局部坐标
坐标系
请记住,用户可能正在使用已创建局部坐标系的工作平面。因此,您创建的形状的方向通常由用户的工作平面隐式定义。
您创建的任何对象都必须在全局坐标中完全定义,即使部分或全部用户输入可能是根据局部坐标定义的。
链接到你的插件中
您的插件是一个单一方法,它附加到主 Workplane 或 CadQuery 对象。
您的插件方法的第一个参数应该是“self”,它将提供对基类功能的引用。您还可以接受其他论点。
要安装它,只需将其附加到 CadQuery 或 Workplane 对象,如下所示:
def _yourFunction(self, arg1, arg):
# do stuff
return whatever_you_want
cq.Workplane.yourPlugin = _yourFunction
就是这样!
CadQuery示例插件
一些核心 cadquery 代码是故意写得像插件一样。如果您正在编写自己的插件,请查看以下方法以获取灵感:
插件示例
这个超级简单的插件为每个堆栈点制作指定大小的立方体。(立方体偏离中心,因为盒子的左下角位于参考点。)
import cadquery as cq
def makeCubes(self, length):
# self refers to the CQ or Workplane object
# inner method that creates a cube
def _singleCube(loc):
# loc is a location in local coordinates
# since we're using eachpoint with useLocalCoordinates=True
return cq.Solid.makeBox(length, length, length, pnt).locate(loc)
# use CQ utility method to iterate over the stack, call our
# method, and convert to/from local coordinates.
return self.eachpoint(_singleCube, True)
length = 10
pnt = cq.Vector(0, 0, 0)
# link the plugin into CadQuery
cq.Workplane.makeCubes = makeCubes
# use the plugin
result = (
cq.Workplane("XY")
.box(6.0, 8.0, 0.5)
.faces(">Z")
.rect(4.0, 4.0, forConstruction=True)
.vertices()
.makeCubes(1.0)
.combineSolids()
)
最后编辑:码峰 更新时间:2024-01-12 17:58